﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;

namespace DeVierKoeden.Dynamicweb.CreateSite.Extensions
{
  internal static class PropertyGridExtensions
  {
    /// <summary>
    /// Hacky way to set the width of the first column with the property names in the grid.
    /// </summary>
    /// <param name="grid">The grid that needs to be changed.</param>
    /// <param name="width">The desired width.</param>
    internal static void SetLabelColumnWidth(this PropertyGrid grid, int width)
    {
      // http://stackoverflow.com/questions/12447156/how-can-i-set-the-column-width-of-a-property-grid
      if (grid == null)
      {
        throw new ArgumentNullException(nameof(grid));
      }
      // get the grid view
      var memberInfo = grid.GetType().GetField("gridView", BindingFlags.Instance | BindingFlags.NonPublic);
      if (memberInfo != null)
      {
        var view = (Control)memberInfo.GetValue(grid);

        // set label width
        var fieldInfo = view.GetType().GetField("labelWidth", BindingFlags.Instance | BindingFlags.NonPublic);
        if (fieldInfo != null)
        {
          fieldInfo.SetValue(view, width);
        }

        // refresh
        view.Invalidate();
      }
    }

    internal static void ResizeDescriptionArea(this PropertyGrid grid, int lines)
    {
      try
      {
        var info = grid.GetType().GetProperty("Controls");
        if (info != null)
        {
          var collection = (Control.ControlCollection)info.GetValue(grid, null);

          foreach (var control in collection)
          {
            var type = control.GetType();

            if ("DocComment" == type.Name)
            {
              const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
              if (type.BaseType != null)
              {
                var field = type.BaseType.GetField("userSized", flags);
                if (field != null)
                {
                  field.SetValue(control, true);
                }
                info = type.GetProperty("Lines");
                if (info != null)
                {
                  info.SetValue(control, lines, null);
                }
              }

              grid.HelpVisible = true;
              break;
            }
          }
        }
      }

      catch (Exception ex)
      {
        Trace.WriteLine(ex);
      }
    }
  }
}
